home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / gepackte_disketten / 1994 / 08_94_5.dms / 08_94_5.adf / term-4.0-Source.lha / termTransfer.c < prev    next >
C/C++ Source or Header  |  1994-07-01  |  35KB  |  1,739 lines

  1. /*
  2. **    termTransfer.c
  3. **
  4. **    File transfer routines
  5. **
  6. **    Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* The action strings to display. */
  13.  
  14. STATIC STRPTR    SendQuery[3],
  15.         ReceiveQuery[3],
  16.         TransferTypes[3];
  17.  
  18.     /* ReplaceName(STRPTR Original):
  19.      *
  20.      *    Replace a filename with a mangled version for
  21.      *    file uploads.
  22.      */
  23.  
  24. STATIC STRPTR __regargs
  25. ReplaceName(STRPTR Source)
  26. {
  27.     if(Config -> TransferConfig -> MangleFileNames)
  28.     {
  29.         UBYTE LocalName[MAX_FILENAME_LENGTH],*Char;
  30.  
  31.         strcpy(OriginalName,Source);
  32.  
  33.         ShrinkName(FilePart(Source),LocalName,12,TRUE);
  34.  
  35.         strcpy(ShrunkenName,Source);
  36.  
  37.         Char = PathPart(ShrunkenName);
  38.  
  39.         *Char = 0;
  40.  
  41.         AddPart(ShrunkenName,LocalName,MAX_FILENAME_LENGTH);
  42.  
  43.         return(ShrunkenName);
  44.     }
  45.     else
  46.     {
  47.         OriginalName[0] = 0;
  48.  
  49.         return(Source);
  50.     }
  51. }
  52.  
  53.     /* FreeFileTransferInfo(struct FileTransferInfo *Info):
  54.      *
  55.      *    Free a file transfer info list as allocated
  56.      *    by AllocFileTransferInfo() and AddFileTransferNode().
  57.      */
  58.  
  59. VOID __regargs
  60. FreeFileTransferInfo(struct FileTransferInfo *Info)
  61. {
  62.     if(Info)
  63.     {
  64.         struct FileTransferNode    *Node,
  65.                     *Next;
  66.  
  67.         Node = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  68.  
  69.         while(Next = (struct FileTransferNode *)Node -> Node . mln_Succ)
  70.         {
  71.             FreeVecPooled(Node);
  72.  
  73.             Node = Next;
  74.         }
  75.  
  76.         FreeVecPooled(Info);
  77.     }
  78. }
  79.  
  80.     /* AllocFileTransferInfo():
  81.      *
  82.      *    Allocate a FileTransferInfo structure for use with
  83.      *    AddFileTransferNode().
  84.      */
  85.  
  86. struct FileTransferInfo *
  87. AllocFileTransferInfo()
  88. {
  89.     struct FileTransferInfo *Info;
  90.  
  91.     if(Info = (struct FileTransferInfo *)AllocVecPooled(sizeof(struct FileTransferInfo),MEMF_ANY | MEMF_CLEAR))
  92.     {
  93.         NewList((struct List *)&Info -> FileList);
  94.  
  95.         return(Info);
  96.     }
  97.  
  98.     return(NULL);
  99. }
  100.  
  101.     /* AddFileTransferNode(struct FileTransferInfo *Info,STRPTR Name,ULONG Size):
  102.      *
  103.      *    Allocate a file transfer information node.
  104.      */
  105.  
  106. BYTE __regargs
  107. AddFileTransferNode(struct FileTransferInfo *Info,STRPTR Name,ULONG Size)
  108. {
  109.     struct FileTransferNode    *Node;
  110.     WORD             Len = strlen(Name) + 1;
  111.  
  112.     if(Node = (struct FileTransferNode *)AllocVecPooled(sizeof(struct FileTransferNode) + Len,MEMF_ANY))
  113.     {
  114.         Node -> Size    = Size;
  115.         Node -> Name    = (STRPTR)(Node + 1);
  116.  
  117.         strcpy(Node -> Name,Name);
  118.  
  119.         AddTail((struct List *)&Info -> FileList,(struct Node *)Node);
  120.  
  121.         Info -> TotalSize += Size;
  122.  
  123.         Info -> TotalFiles++;
  124.  
  125.         return(TRUE);
  126.     }
  127.     else
  128.         return(FALSE);
  129. }
  130.  
  131.     /* Compare(struct FileTransferNode **A,struct FileTransferNode **B):
  132.      *
  133.      *    Local subroutine required by qsort().
  134.      */
  135.  
  136. STATIC int __stdargs
  137. Compare(struct FileTransferNode **A,struct FileTransferNode **B)
  138. {
  139.     return(Stricmp(FilePart((*A) -> Name),FilePart((*B) -> Name)));
  140. }
  141.  
  142.     /* SortFileTransferInfo(struct FileTransferInfo *Info):
  143.      *
  144.      *    Sorts the file transfer information list in ascending
  145.      *    order, but makes sure that the files are sorted
  146.      *    in descending order (i.e. the larger files come
  147.      *    first and files of equal size are sorted
  148.      *    lexically).
  149.      */
  150.  
  151. VOID __regargs
  152. SortFileTransferInfo(struct FileTransferInfo *Info)
  153. {
  154.     if(Info -> TotalFiles > 1)
  155.     {
  156.         struct FileTransferNode **NodeList;
  157.  
  158.         if(NodeList = (struct FileTransferNode **)AllocVecPooled(sizeof(struct FileTransferNode *) * Info -> TotalFiles,MEMF_ANY))
  159.         {
  160.             struct FileTransferNode    *Node,
  161.                         *Next;
  162.             LONG             i = 0;
  163.  
  164.             Node = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  165.  
  166.             while(Next = (struct FileTransferNode *)Node -> Node . mln_Succ)
  167.             {
  168.                 NodeList[i++] = Node;
  169.  
  170.                 Node = Next;
  171.             }
  172.  
  173.             qsort((APTR)NodeList,Info -> TotalFiles,sizeof(struct FileTransferNode *),Compare);
  174.  
  175.             NewList((struct List *)&Info -> FileList);
  176.  
  177.             for(i = 0 ; i < Info -> TotalFiles ; i++)
  178.                 AddTail((struct List *)&Info -> FileList,(struct Node *)&NodeList[i] -> Node);
  179.  
  180.             FreeVecPooled(NodeList);
  181.         }
  182.     }
  183.  
  184.     Info -> DoneSize    = 0;
  185.     Info -> DoneFiles    = 0;
  186.  
  187.     Info -> CurrentFile    = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  188.     Info -> CurrentSize    = Info -> CurrentFile -> Size;
  189. }
  190.  
  191.     /* BuildFileTransferInfo(struct FileRequester *FileRequester):
  192.      *
  193.      *    Build a file transfer information list from
  194.      *    information provided by a FileRequester structure.
  195.      */
  196.  
  197. struct FileTransferInfo * __regargs
  198. BuildFileTransferInfo(struct FileRequester *FileRequester)
  199. {
  200.     struct FileTransferInfo    *Info;
  201.     LONG             FilesFound = 0;
  202.  
  203.     if(Info = AllocFileTransferInfo())
  204.     {
  205.         BYTE    Success = FALSE;
  206.         BPTR    NewLock,
  207.             OldLock;
  208.  
  209.         if(NewLock = Lock(FileRequester -> rf_Dir,ACCESS_READ))
  210.         {
  211.             OldLock = CurrentDir(NewLock);
  212.  
  213.             if(FileRequester -> rf_NumArgs)
  214.             {
  215.                 struct FileInfoBlock *FileInfo;
  216.  
  217.                 if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  218.                 {
  219.                     BPTR         FileLock;
  220.                     struct WBArg    *ArgList = FileRequester -> rf_ArgList;
  221.                     LONG         i;
  222.  
  223.                     Success = TRUE;
  224.  
  225.                     for(i = 0 ; Success && i < FileRequester -> rf_NumArgs ; i++)
  226.                     {
  227.                         if(ArgList[i] . wa_Name)
  228.                         {
  229.                             if(ArgList[i] . wa_Lock)
  230.                             {
  231.                                 CurrentDir(ArgList[i] . wa_Lock);
  232.  
  233.                                 if(FileLock = Lock(ArgList[i] . wa_Name,ACCESS_READ))
  234.                                 {
  235.                                     if(Examine(FileLock,FileInfo))
  236.                                     {
  237.                                         if(FileInfo -> fib_DirEntryType < 0)
  238.                                         {
  239.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  240.                                             {
  241.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  242.                                                     Success = FALSE;
  243.                                                 else
  244.                                                     FilesFound++;
  245.                                             }
  246.                                         }
  247.                                     }
  248.  
  249.                                     UnLock(FileLock);
  250.                                 }
  251.  
  252.                                 CurrentDir(NewLock);
  253.                             }
  254.                             else
  255.                             {
  256.                                 if(FileLock = Lock(ArgList[i] . wa_Name,ACCESS_READ))
  257.                                 {
  258.                                     if(Examine(FileLock,FileInfo))
  259.                                     {
  260.                                         if(FileInfo -> fib_DirEntryType < 0)
  261.                                         {
  262.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  263.                                             {
  264.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  265.                                                     Success = FALSE;
  266.                                                 else
  267.                                                     FilesFound++;
  268.                                             }
  269.                                         }
  270.                                     }
  271.  
  272.                                     UnLock(FileLock);
  273.                                 }
  274.                             }
  275.                         }
  276.                     }
  277.                 }
  278.  
  279.                 FreeDosObject(DOS_FIB,FileInfo);
  280.             }
  281.             else
  282.             {
  283.                 struct AnchorPath *Anchor;
  284.  
  285.                 STRPTR FileName;
  286.  
  287.                 if(FileRequester -> rf_NumArgs > 1 && FileRequester -> rf_ArgList)
  288.                     FileName = FileRequester -> rf_ArgList -> wa_Name;
  289.                 else
  290.                     FileName = FileRequester -> rf_File;
  291.  
  292.                 if(Anchor = (struct AnchorPath *)AllocVecPooled(sizeof(struct AnchorPath),MEMF_ANY | MEMF_CLEAR))
  293.                 {
  294.                     if(!MatchFirst(FileName,Anchor))
  295.                     {
  296.                         Success = TRUE;
  297.  
  298.                         if(Anchor -> ap_Info . fib_DirEntryType < 0)
  299.                         {
  300.                             if(NameFromLock(NewLock,SharedBuffer,512))
  301.                             {
  302.                                 if(AddPart(SharedBuffer,Anchor -> ap_Info . fib_FileName,512))
  303.                                 {
  304.                                     if(!AddFileTransferNode(Info,SharedBuffer,Anchor -> ap_Info . fib_Size))
  305.                                         Success = FALSE;
  306.                                     else
  307.                                         FilesFound++;
  308.                                 }
  309.                             }
  310.                         }
  311.  
  312.                         if(Success)
  313.                         {
  314.                             while(!MatchNext(Anchor))
  315.                             {
  316.                                 if(NameFromLock(NewLock,SharedBuffer,512))
  317.                                 {
  318.                                     if(AddPart(SharedBuffer,Anchor -> ap_Info . fib_FileName,512))
  319.                                     {
  320.                                         if(!AddFileTransferNode(Info,SharedBuffer,Anchor -> ap_Info . fib_Size))
  321.                                         {
  322.                                             Success = FALSE;
  323.  
  324.                                             break;
  325.                                         }
  326.                                         else
  327.                                             FilesFound++;
  328.                                     }
  329.                                 }
  330.                             }
  331.                         }
  332.  
  333.                         if(IoErr() != ERROR_NO_MORE_ENTRIES)
  334.                             Success = FALSE;
  335.                     }
  336.  
  337.                     MatchEnd(Anchor);
  338.  
  339.                     FreeVecPooled(Anchor);
  340.                 }
  341.             }
  342.  
  343.             CurrentDir(OldLock);
  344.  
  345.             UnLock(NewLock);
  346.         }
  347.  
  348.         if(Success && FilesFound)
  349.         {
  350.             SortFileTransferInfo(Info);
  351.  
  352.             return(Info);
  353.         }
  354.         else
  355.             FreeFileTransferInfo(Info);
  356.     }
  357.  
  358.     return(NULL);
  359. }
  360.  
  361.     /* SendTextFile(STRPTR TheFile):
  362.      *
  363.      *    Send a single text file via xpr.
  364.      */
  365.  
  366. VOID __regargs
  367. SendTextFile(BYTE Type,STRPTR TheFile)
  368. {
  369.     TheFile = ReplaceName(TheFile);
  370.  
  371.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> InternalASCIIUpload)
  372.         InternalASCIIUpload(TheFile,TRUE);
  373.     else
  374.     {
  375.         BYTE OldStatus = Status;
  376.         BPTR NewDir,OldDir;
  377.  
  378.         if(Type == TRANSFER_ASCII)
  379.             NewDir = Lock(Config -> PathConfig -> ASCIIUploadPath,ACCESS_READ);
  380.         else
  381.             NewDir = Lock(Config -> PathConfig -> TextUploadPath,ACCESS_READ);
  382.  
  383.         if(NewDir)
  384.             OldDir = CurrentDir(NewDir);
  385.         else
  386.             OldDir = NULL;
  387.  
  388.         Uploading = TRUE;
  389.  
  390.         LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
  391.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  392.  
  393.             /* If not initialized, try to set up a new
  394.              * external transfer protocol.
  395.              */
  396.  
  397.         if(!XProtocolBase)
  398.         {
  399.             if(SelectProtocol(LastXprLibrary,Window))
  400.             {
  401.                 if(ProtocolSetup(FALSE))
  402.                 {
  403.                     SaveProtocolOpts();
  404.  
  405.                     strcpy(Config -> FileConfig -> ProtocolFileName,LastXprLibrary);
  406.                 }
  407.             }
  408.         }
  409.  
  410.         if(XProtocolBase)
  411.         {
  412.             SetTransferMenu(TRUE);
  413.  
  414.             XprIO -> xpr_filename = TheFile;
  415.  
  416.             if(TransferPanel(SendQuery[TRANSFER_TEXT]))
  417.             {
  418.                 Status = STATUS_UPLOAD;
  419.  
  420.                 ClearSerial();
  421.  
  422.                 LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[TRANSFER_TEXT]);
  423.  
  424.                 if(ReadRequest && WriteRequest)
  425.                 {
  426.                     if(XProtocolSend(XprIO))
  427.                         TransferFailed = FALSE;
  428.                     else
  429.                         TransferFailed = TRUE;
  430.                 }
  431.                 else
  432.                     TransferFailed = TRUE;
  433.  
  434.                 if(TransferFailed || TransferAborted)
  435.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  436.                 else
  437.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  438.  
  439.                 if(TransferFailed || TransferError)
  440.                 {
  441.                     WakeUp(TransferWindow,SOUND_BADTRANSFER);
  442.  
  443.                     DeleteTransferPanel(TRUE);
  444.                 }
  445.                 else
  446.                 {
  447.                     if(TransferWindow)
  448.                     {
  449.                         WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  450.  
  451.                         WaitTime(2,0);
  452.                     }
  453.  
  454.                     DeleteTransferPanel(FALSE);
  455.                 }
  456.  
  457.                 Status = OldStatus;
  458.  
  459.                 RestartSerial(FALSE);
  460.             }
  461.         }
  462.         else
  463.             SetTransferMenu(FALSE);
  464.  
  465.         if(OldDir)
  466.             CurrentDir(OldDir);
  467.  
  468.         if(NewDir)
  469.             UnLock(NewDir);
  470.  
  471.         if(SendAbort && UsesZModem)
  472.             SerWrite(ZModemCancel,20);
  473.  
  474.         SendAbort = FALSE;
  475.  
  476.         Uploading = FALSE;
  477.  
  478.         if(Config -> CommandConfig -> UploadMacro[0])
  479.             SerialCommand(Config -> CommandConfig -> UploadMacro);
  480.  
  481.         DidTransfer = FALSE;
  482.     }
  483. }
  484.  
  485.     /* StartXprReceive():
  486.      *
  487.      *    Receive files via xpr.
  488.      */
  489.  
  490. VOID __regargs
  491. StartXprReceive(BYTE Type,STRPTR Name,BYTE WaitForIt)
  492. {
  493.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> InternalASCIIDownload)
  494.         InternalASCIIDownload(Name,WaitForIt);
  495.     else
  496.     {
  497.         struct FileRequester    *FileRequest;
  498.         UBYTE             DummyBuffer[MAX_FILENAME_LENGTH];
  499.         BYTE             OldStatus = Status;
  500.         BPTR             NewDir,OldDir;
  501.  
  502.         ClearGenericList(GenericListTable[GLIST_DOWNLOAD]);
  503.  
  504.         LocalizeString(ReceiveQuery,MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT,MSG_TERMTRANSFER_DOWNLOAD_ASCII_TXT);
  505.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  506.  
  507.             /* Select the download path. */
  508.  
  509.         switch(Type)
  510.         {
  511.             case TRANSFER_BINARY:
  512.  
  513.                 DownloadPath = Config -> PathConfig -> BinaryDownloadPath;
  514.                 break;
  515.  
  516.             case TRANSFER_TEXT:
  517.  
  518.                 DownloadPath = Config -> PathConfig -> TextDownloadPath;
  519.                 break;
  520.  
  521.             case TRANSFER_ASCII:
  522.  
  523.                 DownloadPath = Config -> PathConfig -> ASCIIDownloadPath;
  524.                 break;
  525.         }
  526.  
  527.         if(DownloadPath[0])
  528.         {
  529.             if(NewDir = Lock(DownloadPath,ACCESS_READ))
  530.                 OldDir = CurrentDir(NewDir);
  531.             else
  532.                 OldDir = NULL;
  533.         }
  534.         else
  535.             NewDir = OldDir = NULL;
  536.  
  537.         BlockWindows();
  538.  
  539.             /* Set up the library if necessary. */
  540.  
  541.         if(!XProtocolBase)
  542.         {
  543.             if(SelectProtocol(LastXprLibrary,Window))
  544.             {
  545.                 if(ProtocolSetup(FALSE))
  546.                 {
  547.                     SaveProtocolOpts();
  548.  
  549.                     strcpy(Config -> FileConfig -> ProtocolFileName,LastXprLibrary);
  550.                 }
  551.             }
  552.         }
  553.  
  554.         if(XProtocolBase)
  555.         {
  556.             SetTransferMenu(TRUE);
  557.  
  558.                 /* Do we need to ask the user for
  559.                  * the destination file name?
  560.                  */
  561.  
  562.             if(TransferBits & XPRS_NORECREQ)
  563.             {
  564.                     /* Obviously not, let's open
  565.                      * the transfer info window as
  566.                      * usual and download the file(s).
  567.                      */
  568.  
  569.                 if(TransferPanel(ReceiveQuery[Type]))
  570.                 {
  571.                     Status = STATUS_DOWNLOAD;
  572.  
  573.                     ClearSerial();
  574.  
  575.                     LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),TransferTypes[Type]);
  576.  
  577.                         /* Receive the data. */
  578.  
  579.                     if(ReadRequest && WriteRequest)
  580.                     {
  581.                         if(XProtocolReceive(XprIO))
  582.                             TransferFailed = FALSE;
  583.                         else
  584.                             TransferFailed = TRUE;
  585.                     }
  586.                     else
  587.                         TransferFailed = TRUE;
  588.  
  589.                         /* In case the transfer has been aborted,
  590.                          * flush the input buffer of dirty data.
  591.                          */
  592.  
  593.                     if(TransferAborted)
  594.                         xpr_sflush();
  595.  
  596.                     if(TransferAborted || TransferFailed)
  597.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  598.                     else
  599.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  600.  
  601.                     if(TransferFailed || TransferError)
  602.                     {
  603.                         WakeUp(TransferWindow,SOUND_BADTRANSFER);
  604.  
  605.                         DeleteTransferPanel(WaitForIt);
  606.                     }
  607.                     else
  608.                     {
  609.                         if(TransferWindow)
  610.                         {
  611.                             WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  612.  
  613.                             WaitTime(2,0);
  614.                         }
  615.  
  616.                         DeleteTransferPanel(FALSE);
  617.                     }
  618.  
  619.                     Status = OldStatus;
  620.  
  621.                         /* Queue another read request. */
  622.  
  623.                     RestartSerial(FALSE);
  624.                 }
  625.             }
  626.             else
  627.             {
  628.                 if(!Name)
  629.                 {
  630.                     if(FileRequest = GetFile(Window,ReceiveQuery[Type],DownloadPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE))
  631.                     {
  632.                             /* Save the download path. */
  633.  
  634.                         strcpy(DownloadPath,FileRequest -> rf_Dir);
  635.  
  636.                         ConfigChanged = TRUE;
  637.  
  638.                             /* Install the name of the file to receive. */
  639.  
  640.                         XprIO -> xpr_filename = DummyBuffer;
  641.  
  642.                         FreeAslRequest(FileRequest);
  643.  
  644.                         Name = DummyBuffer;
  645.                     }
  646.                 }
  647.                 else
  648.                 {
  649.                     STRPTR Index;
  650.  
  651.                     strcpy(DownloadPath,Name);
  652.  
  653.                     ConfigChanged = TRUE;
  654.  
  655.                     Index = PathPart(DownloadPath);
  656.  
  657.                     *Index = 0;
  658.  
  659.                     XprIO -> xpr_filename = Name;
  660.                 }
  661.  
  662.                     /* Download the file(s). */
  663.  
  664.                 if(Name)
  665.                 {
  666.                         /* Open the transfer panel. */
  667.  
  668.                     if(TransferPanel(ReceiveQuery[Type]))
  669.                     {
  670.                         Status = STATUS_DOWNLOAD;
  671.  
  672.                         ClearSerial();
  673.  
  674.                         LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),TransferTypes[Type]);
  675.  
  676.                             /* Receive the file. */
  677.  
  678.                         if(ReadRequest && WriteRequest)
  679.                         {
  680.                             if(XProtocolReceive(XprIO))
  681.                                 TransferFailed = FALSE;
  682.                             else
  683.                                 TransferFailed = TRUE;
  684.                         }
  685.                         else
  686.                             TransferFailed = TRUE;
  687.  
  688.                             /* In case the transfer has been aborted,
  689.                              * flush the input buffer of dirty data.
  690.                              */
  691.  
  692.                         if(TransferAborted)
  693.                             xpr_sflush();
  694.  
  695.                         if(TransferAborted || TransferFailed)
  696.                             Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  697.                         else
  698.                             Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  699.  
  700.                         if(TransferFailed || TransferError)
  701.                         {
  702.                             WakeUp(TransferWindow,SOUND_BADTRANSFER);
  703.  
  704.                             DeleteTransferPanel(WaitForIt);
  705.                         }
  706.                         else
  707.                         {
  708.                             if(TransferWindow)
  709.                             {
  710.                                 WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  711.  
  712.                                 WaitTime(2,0);
  713.                             }
  714.  
  715.                             DeleteTransferPanel(FALSE);
  716.                         }
  717.  
  718.                         Status = OldStatus;
  719.  
  720.                             /* Queue another read
  721.                              * request.
  722.                              */
  723.  
  724.                         RestartSerial(FALSE);
  725.                     }
  726.                 }
  727.             }
  728.         }
  729.         else
  730.             SetTransferMenu(FALSE);
  731.  
  732.         if(OldDir)
  733.             CurrentDir(OldDir);
  734.  
  735.         if(NewDir)
  736.             UnLock(NewDir);
  737.  
  738.         if(SendAbort && UsesZModem)
  739.             SerWrite(ZModemCancel,20);
  740.  
  741.         SendAbort = FALSE;
  742.  
  743.         ReleaseWindows();
  744.  
  745.         DownloadPath = NULL;
  746.  
  747.         DidTransfer = FALSE;
  748.  
  749.         if(WaitForIt)
  750.         {
  751.             if(Config -> CommandConfig -> DownloadMacro[0])
  752.                 SerialCommand(Config -> CommandConfig -> DownloadMacro);
  753.         }
  754.     }
  755. }
  756.  
  757.     /* StartXprSend():
  758.      *
  759.      *    Send files via xpr.
  760.      */
  761.  
  762. BYTE __regargs
  763. StartXprSend(BYTE Type,BYTE WaitForIt)
  764. {
  765.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> InternalASCIIUpload)
  766.         return(InternalASCIIUpload(NULL,WaitForIt));
  767.     else
  768.     {
  769.         struct FileRequester    *FileRequest;
  770.         UBYTE             DummyBuffer[MAX_FILENAME_LENGTH];
  771.         BYTE             OldStatus = Status;
  772.         STRPTR             UploadPath;
  773.         BYTE             DidSend = TRUE;
  774.         BPTR             NewDir,OldDir;
  775.  
  776.         LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
  777.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  778.  
  779.             /* We are uploading data. */
  780.  
  781.         Uploading = TRUE;
  782.  
  783.             /* Select the upload path. */
  784.  
  785.         switch(Type)
  786.         {
  787.             case TRANSFER_BINARY:
  788.  
  789.                 UploadPath = Config -> PathConfig -> BinaryUploadPath;
  790.                 break;
  791.  
  792.             case TRANSFER_TEXT:
  793.  
  794.                 UploadPath = Config -> PathConfig -> TextUploadPath;
  795.                 break;
  796.  
  797.             case TRANSFER_ASCII:
  798.  
  799.                 UploadPath = Config -> PathConfig -> ASCIIUploadPath;
  800.                 break;
  801.         }
  802.  
  803.         if(UploadPath[0])
  804.         {
  805.             if(NewDir = Lock(UploadPath,ACCESS_READ))
  806.                 OldDir = CurrentDir(NewDir);
  807.             else
  808.                 OldDir = NULL;
  809.         }
  810.         else
  811.             NewDir = OldDir = NULL;
  812.  
  813.         BlockWindows();
  814.  
  815.             /* If not initialized, try to set up a new
  816.              * external transfer protocol.
  817.              */
  818.  
  819.         if(!XProtocolBase)
  820.         {
  821.             if(SelectProtocol(LastXprLibrary,Window))
  822.             {
  823.                 if(ProtocolSetup(FALSE))
  824.                 {
  825.                     SaveProtocolOpts();
  826.  
  827.                     strcpy(Config -> FileConfig -> ProtocolFileName,LastXprLibrary);
  828.                 }
  829.             }
  830.         }
  831.  
  832.         if(XProtocolBase)
  833.         {
  834.             SetTransferMenu(TRUE);
  835.  
  836.                 /* Do we need to use our own file requester or
  837.                  * will xpr handle this job for us?
  838.                  */
  839.  
  840.             if(TransferBits & XPRS_NOSNDREQ)
  841.             {
  842.                     /* Open the transfer info window. */
  843.  
  844.                 if(TransferPanel(SendQuery[Type]))
  845.                 {
  846.                     Status = STATUS_UPLOAD;
  847.  
  848.                         /* Shut up the serial line. */
  849.  
  850.                     ClearSerial();
  851.  
  852.                     LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
  853.  
  854.                         /* Perform upload. */
  855.  
  856.                     if(ReadRequest && WriteRequest)
  857.                     {
  858.                         if(XProtocolSend(XprIO))
  859.                             TransferFailed = FALSE;
  860.                         else
  861.                             TransferFailed = TRUE;
  862.                     }
  863.                     else
  864.                         TransferFailed = TRUE;
  865.  
  866.                     if(TransferFailed || TransferAborted)
  867.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  868.                     else
  869.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  870.  
  871.                     if(TransferFailed || TransferError)
  872.                     {
  873.                         WakeUp(TransferWindow,SOUND_BADTRANSFER);
  874.  
  875.                         DeleteTransferPanel(WaitForIt);
  876.                     }
  877.                     else
  878.                     {
  879.                         if(TransferWindow)
  880.                         {
  881.                             WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  882.  
  883.                             WaitTime(2,0);
  884.                         }
  885.  
  886.                         DeleteTransferPanel(FALSE);
  887.                     }
  888.  
  889.                     Status = OldStatus;
  890.  
  891.                         /* And request another character. */
  892.  
  893.                     RestartSerial(FALSE);
  894.                 }
  895.             }
  896.             else
  897.             {
  898.                     /* We will need the file requester to find
  899.                      * out which file(s) are to be transferred.
  900.                      * Multiple files and wildcards are
  901.                      * supported as well as plain file names.
  902.                      */
  903.  
  904.                 if(FileRequest = GetFile(Window,SendQuery[Type],UploadPath,"",DummyBuffer,"",FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),TRUE))
  905.                 {
  906.                     strcpy(UploadPath,FileRequest -> rf_Dir);
  907.  
  908.                     ConfigChanged = TRUE;
  909.  
  910.                     if(FileTransferInfo = BuildFileTransferInfo(FileRequest))
  911.                     {
  912.                             /* Make sure that at least the
  913.                              * first file gets transferred
  914.                              * in case the protocol does
  915.                              * no support batch upload.
  916.                              */
  917.  
  918.                         XprIO -> xpr_filename = ReplaceName(FileTransferInfo -> CurrentFile -> Name);
  919.  
  920.                         if(TransferPanel(SendQuery[Type]))
  921.                         {
  922.                             Status = STATUS_UPLOAD;
  923.  
  924.                             ClearSerial();
  925.  
  926.                             LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
  927.  
  928.                             if(ReadRequest && WriteRequest)
  929.                             {
  930.                                 if(XProtocolSend(XprIO))
  931.                                     TransferFailed = FALSE;
  932.                                 else
  933.                                     TransferFailed = TRUE;
  934.                             }
  935.                             else
  936.                                 TransferFailed = TRUE;
  937.  
  938.                             if(TransferFailed || TransferAborted)
  939.                                 Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  940.                             else
  941.                                 Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  942.  
  943.                             if(TransferFailed || TransferError)
  944.                             {
  945.                                 WakeUp(TransferWindow,SOUND_BADTRANSFER);
  946.  
  947.                                 DeleteTransferPanel(WaitForIt);
  948.                             }
  949.                             else
  950.                             {
  951.                                 if(TransferWindow)
  952.                                 {
  953.                                     WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  954.  
  955.                                     WaitTime(2,0);
  956.                                 }
  957.  
  958.                                 DeleteTransferPanel(FALSE);
  959.                             }
  960.  
  961.                             Status = OldStatus;
  962.  
  963.                             RestartSerial(FALSE);
  964.                         }
  965.                         else
  966.                             MyEasyRequest(Window,LocaleString(MSG_TERMTRANSFER_FAILED_TO_LOCATE_DIRECTORY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FileRequest -> rf_Dir);
  967.  
  968.                         if(FileTransferInfo)
  969.                         {
  970.                             FreeFileTransferInfo(FileTransferInfo);
  971.  
  972.                             FileTransferInfo = NULL;
  973.                         }
  974.                     }
  975.  
  976.                     FreeAslRequest(FileRequest);
  977.                 }
  978.                 else
  979.                     DidSend = FALSE;
  980.             }
  981.         }
  982.         else
  983.             SetTransferMenu(FALSE);
  984.  
  985.         if(OldDir)
  986.             CurrentDir(OldDir);
  987.  
  988.         if(NewDir)
  989.             UnLock(NewDir);
  990.  
  991.         if(SendAbort && UsesZModem)
  992.             SerWrite(ZModemCancel,20);
  993.  
  994.         SendAbort = FALSE;
  995.  
  996.         ReleaseWindows();
  997.  
  998.         Uploading = FALSE;
  999.  
  1000.         if(WaitForIt)
  1001.         {
  1002.             if(Config -> CommandConfig -> UploadMacro[0])
  1003.                 SerialCommand(Config -> CommandConfig -> UploadMacro);
  1004.         }
  1005.  
  1006.         DidTransfer = FALSE;
  1007.  
  1008.         return(DidSend);
  1009.     }
  1010. }
  1011.  
  1012.     /* StartXprSendFromList():
  1013.      *
  1014.      *    Send files via xpr.
  1015.      */
  1016.  
  1017. BYTE __regargs
  1018. StartXprSendFromList(BYTE Type,BYTE WaitForIt)
  1019. {
  1020.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> InternalASCIIUpload)
  1021.         return(InternalASCIIUpload(NULL,WaitForIt));
  1022.     else
  1023.     {
  1024.         BYTE    OldStatus    = Status,
  1025.             DidSend        = TRUE;
  1026.         BPTR    NewDir,
  1027.             OldDir;
  1028.         STRPTR    UploadPath;
  1029.  
  1030.         LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
  1031.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1032.  
  1033.             /* We are uploading data. */
  1034.  
  1035.         Uploading = TRUE;
  1036.  
  1037.         switch(Type)
  1038.         {
  1039.             case TRANSFER_BINARY:
  1040.  
  1041.                 UploadPath = Config -> PathConfig -> BinaryUploadPath;
  1042.                 break;
  1043.  
  1044.             case TRANSFER_TEXT:
  1045.  
  1046.                 UploadPath = Config -> PathConfig -> TextUploadPath;
  1047.                 break;
  1048.  
  1049.             case TRANSFER_ASCII:
  1050.  
  1051.                 UploadPath = Config -> PathConfig -> ASCIIUploadPath;
  1052.                 break;
  1053.         }
  1054.  
  1055.         if(UploadPath[0])
  1056.         {
  1057.             if(NewDir = Lock(UploadPath,ACCESS_READ))
  1058.                 OldDir = CurrentDir(NewDir);
  1059.             else
  1060.                 OldDir = NULL;
  1061.         }
  1062.         else
  1063.             NewDir = OldDir = NULL;
  1064.  
  1065.         BlockWindows();
  1066.  
  1067.             /* If not initialized, try to set up a new
  1068.              * external transfer protocol.
  1069.              */
  1070.  
  1071.         if(!XProtocolBase)
  1072.         {
  1073.             if(WaitForIt)
  1074.             {
  1075.                 if(SelectProtocol(LastXprLibrary,Window))
  1076.                 {
  1077.                     if(ProtocolSetup(FALSE))
  1078.                     {
  1079.                         SaveProtocolOpts();
  1080.  
  1081.                         strcpy(Config -> FileConfig -> ProtocolFileName,LastXprLibrary);
  1082.                     }
  1083.                 }
  1084.             }
  1085.         }
  1086.  
  1087.         if(XProtocolBase)
  1088.         {
  1089.             SetTransferMenu(TRUE);
  1090.  
  1091.                 /* Make sure that at least the
  1092.                  * first file gets transferred
  1093.                  * in case the protocol does
  1094.                  * no support batch upload.
  1095.                  */
  1096.  
  1097.             XprIO -> xpr_filename = ReplaceName(FileTransferInfo -> CurrentFile -> Name);
  1098.  
  1099.             if(TransferPanel(SendQuery[Type]))
  1100.             {
  1101.                 Status = STATUS_UPLOAD;
  1102.  
  1103.                 ClearSerial();
  1104.  
  1105.                 LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
  1106.  
  1107.                 if(ReadRequest && WriteRequest)
  1108.                 {
  1109.                     if(XProtocolSend(XprIO))
  1110.                         TransferFailed = FALSE;
  1111.                     else
  1112.                         TransferFailed = TRUE;
  1113.                 }
  1114.                 else
  1115.                     TransferFailed = TRUE;
  1116.  
  1117.                 if(TransferFailed || TransferAborted)
  1118.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1119.                 else
  1120.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1121.  
  1122.                 if(TransferFailed || TransferError)
  1123.                 {
  1124.                     WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1125.  
  1126.                     DeleteTransferPanel(WaitForIt);
  1127.                 }
  1128.                 else
  1129.                 {
  1130.                     if(TransferWindow)
  1131.                     {
  1132.                         WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1133.  
  1134.                         WaitTime(2,0);
  1135.                     }
  1136.  
  1137.                     DeleteTransferPanel(FALSE);
  1138.                 }
  1139.  
  1140.                 Status = OldStatus;
  1141.  
  1142.                 RestartSerial(FALSE);
  1143.             }
  1144.  
  1145.             if(FileTransferInfo)
  1146.             {
  1147.                 FreeFileTransferInfo(FileTransferInfo);
  1148.  
  1149.                 FileTransferInfo = NULL;
  1150.             }
  1151.         }
  1152.         else
  1153.         {
  1154.             SetTransferMenu(FALSE);
  1155.  
  1156.             DidSend = FALSE;
  1157.         }
  1158.  
  1159.         if(OldDir)
  1160.             CurrentDir(OldDir);
  1161.  
  1162.         if(NewDir)
  1163.             UnLock(NewDir);
  1164.  
  1165.         if(SendAbort && UsesZModem)
  1166.             SerWrite(ZModemCancel,20);
  1167.  
  1168.         SendAbort = FALSE;
  1169.  
  1170.         ReleaseWindows();
  1171.  
  1172.         Uploading = FALSE;
  1173.  
  1174.         if(WaitForIt)
  1175.         {
  1176.             if(Config -> CommandConfig -> UploadMacro[0])
  1177.                 SerialCommand(Config -> CommandConfig -> UploadMacro);
  1178.         }
  1179.  
  1180.         DidTransfer = FALSE;
  1181.  
  1182.         return(DidSend);
  1183.     }
  1184. }
  1185.  
  1186.     /* ChangeProtocol(STRPTR ProtocolName):
  1187.      *
  1188.      *    Select a different file transfer protocol.
  1189.      */
  1190.  
  1191. BYTE __regargs
  1192. ChangeProtocol(STRPTR ProtocolName)
  1193. {
  1194.     UBYTE NameBuffer[40],i;
  1195.  
  1196.     if(!ProtocolName || !ProtocolName[0])
  1197.         ProtocolName = Config -> TransferConfig -> DefaultLibrary;
  1198.  
  1199.     if(!Stricmp(ProtocolName,LastXprLibrary) && XProtocolBase)
  1200.         return(TRUE);
  1201.  
  1202.         /* Close the old library if still open. */
  1203.  
  1204.     if(XProtocolBase)
  1205.     {
  1206.         XProtocolCleanup(XprIO);
  1207.  
  1208.         CloseLibrary(XProtocolBase);
  1209.  
  1210.         XProtocolBase = NULL;
  1211.  
  1212.         SetTransferMenu(FALSE);
  1213.     }
  1214.  
  1215.         /* Clear the XPR interface buffer. */
  1216.  
  1217.     memset(XprIO,0,sizeof(struct XPR_IO));
  1218.  
  1219.         /* Copy the name of the library. */
  1220.  
  1221.     strcpy(NameBuffer,FilePart(ProtocolName));
  1222.  
  1223.         /* Extract the name itself (strip the `.library'). */
  1224.  
  1225.     for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  1226.     {
  1227.         if(NameBuffer[i] == '.')
  1228.         {
  1229.             NameBuffer[i] = 0;
  1230.  
  1231.             break;
  1232.         }
  1233.     }
  1234.  
  1235.         /* Check if the transfer protocol is a sort of ZModem. */
  1236.  
  1237.     UsesZModem = FALSE;
  1238.  
  1239.     for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  1240.     {
  1241.         if(!Stricmp(&NameBuffer[i],"zmodem"))
  1242.             UsesZModem = TRUE;
  1243.     }
  1244.  
  1245.         /* Reset the scanner. */
  1246.  
  1247.     FlowInit(TRUE);
  1248.  
  1249.         /* Obtain the protocol default settings. */
  1250.  
  1251.     if(!GetEnvDOS(NameBuffer,ProtocolOptsBuffer))
  1252.         ProtocolOptsBuffer[0] = 0;
  1253.  
  1254.         /* Initialize the interface structure. */
  1255.  
  1256.     XprIO -> xpr_filename    = ProtocolOptsBuffer;
  1257.     XprIO -> xpr_fopen    = xpr_fopen;
  1258.     XprIO -> xpr_fclose    = xpr_fclose;
  1259.     XprIO -> xpr_fread    = xpr_fread;
  1260.     XprIO -> xpr_fwrite    = xpr_fwrite;
  1261.     XprIO -> xpr_sread    = xpr_sread;
  1262.     XprIO -> xpr_swrite    = xpr_swrite;
  1263.     XprIO -> xpr_sflush    = xpr_sflush;
  1264.     XprIO -> xpr_update    = xpr_update;
  1265.     XprIO -> xpr_chkabort    = xpr_chkabort;
  1266.     XprIO -> xpr_gets    = xpr_gets;
  1267.     XprIO -> xpr_setserial    = xpr_setserial;
  1268.     XprIO -> xpr_ffirst    = xpr_ffirst;
  1269.     XprIO -> xpr_fnext    = xpr_fnext;
  1270.     XprIO -> xpr_finfo    = xpr_finfo;
  1271.     XprIO -> xpr_fseek    = xpr_fseek;
  1272.     XprIO -> xpr_extension    = 4;
  1273.     XprIO -> xpr_options    = xpr_options;
  1274.     XprIO -> xpr_unlink    = xpr_unlink;
  1275.     XprIO -> xpr_squery    = xpr_squery;
  1276.     XprIO -> xpr_getptr    = xpr_getptr;
  1277.  
  1278.         /* Try to open the library. */
  1279.  
  1280.     if(XProtocolBase = (struct Library *)OpenLibrary(ProtocolName,0))
  1281.     {
  1282.             /* Set up the library. */
  1283.  
  1284.         ClearSerial();
  1285.  
  1286.         TransferBits = XProtocolSetup(XprIO);
  1287.  
  1288.         RestartSerial(FALSE);
  1289.  
  1290.         DeleteTransferPanel(TRUE);
  1291.  
  1292.             /* Successful initialization? */
  1293.  
  1294.         if(TransferBits & XPRS_SUCCESS)
  1295.         {
  1296.             SetTransferMenu(TRUE);
  1297.  
  1298.             strcpy(LastXprLibrary,ProtocolName);
  1299.  
  1300.             if(TransferBits & XPRS_HOSTMON)
  1301.                 ConTransfer = ConTransferHost;
  1302.             else
  1303.                 ConTransfer = ConProcess;
  1304.  
  1305.             if(TransferBits & XPRS_HOSTNOWAIT)
  1306.             {
  1307.                 if(!HostReadBuffer)
  1308.                     HostReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
  1309.             }
  1310.             else
  1311.             {
  1312.                 if(HostReadBuffer)
  1313.                 {
  1314.                     FreeVecPooled(HostReadBuffer);
  1315.  
  1316.                     HostReadBuffer = NULL;
  1317.                 }
  1318.             }
  1319.  
  1320.             return(TRUE);
  1321.         }
  1322.         else
  1323.         {
  1324.             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),ProtocolName);
  1325.  
  1326.             CloseLibrary(XProtocolBase);
  1327.  
  1328.             XProtocolBase = NULL;
  1329.  
  1330.             SetTransferMenu(FALSE);
  1331.  
  1332.             LastXprLibrary[0] = 0;
  1333.  
  1334.             TransferBits = 0;
  1335.  
  1336.             ConTransfer = ConProcess;
  1337.         }
  1338.     }
  1339.     else
  1340.     {
  1341.         ConTransfer = ConProcess;
  1342.  
  1343.         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),ProtocolName);
  1344.     }
  1345.  
  1346.     return(FALSE);
  1347. }
  1348.  
  1349.     /* ResetProtocol():
  1350.      *
  1351.      *    Return to the previously selected file
  1352.      *    transfer protocol.
  1353.      */
  1354.  
  1355. VOID
  1356. ResetProtocol()
  1357. {
  1358.     ChangeProtocol(NULL);
  1359. }
  1360.  
  1361.     /* ProtocolSetup(BYTE IgnoreOptions):
  1362.      *
  1363.      *    Set up the library and options for the external protocol.
  1364.      */
  1365.  
  1366. BYTE __regargs
  1367. ProtocolSetup(BYTE IgnoreOptions)
  1368. {
  1369.     UBYTE NameBuffer[40],i;
  1370.  
  1371.         /* Close the old library if still open. */
  1372.  
  1373.     if(XProtocolBase)
  1374.     {
  1375.         XProtocolCleanup(XprIO);
  1376.  
  1377.         CloseLibrary(XProtocolBase);
  1378.  
  1379.         XProtocolBase = NULL;
  1380.  
  1381.         SetTransferMenu(FALSE);
  1382.     }
  1383.  
  1384.         /* Clear the XPR interface buffer. */
  1385.  
  1386.     memset(XprIO,0,sizeof(struct XPR_IO));
  1387.  
  1388.         /* Copy the name of the library. */
  1389.  
  1390.     strcpy(NameBuffer,FilePart(LastXprLibrary));
  1391.  
  1392.         /* Extract the name itself (strip the `.library'). */
  1393.  
  1394.     for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  1395.     {
  1396.         if(NameBuffer[i] == '.')
  1397.         {
  1398.             NameBuffer[i] = 0;
  1399.             break;
  1400.         }
  1401.     }
  1402.  
  1403.         /* Check if the transfer protocol is a sort of ZModem. */
  1404.  
  1405.     UsesZModem = FALSE;
  1406.  
  1407.     for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  1408.     {
  1409.         if(!Stricmp(&NameBuffer[i],"zmodem"))
  1410.             UsesZModem = TRUE;
  1411.     }
  1412.  
  1413.         /* Reset the scanner. */
  1414.  
  1415.     FlowInit(TRUE);
  1416.  
  1417.         /* Obtain the protocol default settings. */
  1418.  
  1419.     if(!IgnoreOptions)
  1420.     {
  1421.         if(!GetEnvDOS(NameBuffer,ProtocolOptsBuffer))
  1422.             ProtocolOptsBuffer[0] = 0;
  1423.     }
  1424.  
  1425.         /* Initialize the interface structure. */
  1426.  
  1427.     XprIO -> xpr_filename    = ProtocolOptsBuffer;
  1428.     XprIO -> xpr_fopen    = xpr_fopen;
  1429.     XprIO -> xpr_fclose    = xpr_fclose;
  1430.     XprIO -> xpr_fread    = xpr_fread;
  1431.     XprIO -> xpr_fwrite    = xpr_fwrite;
  1432.     XprIO -> xpr_sread    = xpr_sread;
  1433.     XprIO -> xpr_swrite    = xpr_swrite;
  1434.     XprIO -> xpr_sflush    = xpr_sflush;
  1435.     XprIO -> xpr_update    = xpr_update;
  1436.     XprIO -> xpr_chkabort    = xpr_chkabort;
  1437.     XprIO -> xpr_gets    = xpr_gets;
  1438.     XprIO -> xpr_setserial    = xpr_setserial;
  1439.     XprIO -> xpr_ffirst    = xpr_ffirst;
  1440.     XprIO -> xpr_fnext    = xpr_fnext;
  1441.     XprIO -> xpr_finfo    = xpr_finfo;
  1442.     XprIO -> xpr_fseek    = xpr_fseek;
  1443.     XprIO -> xpr_extension    = 4;
  1444.     XprIO -> xpr_options    = xpr_options;
  1445.     XprIO -> xpr_unlink    = xpr_unlink;
  1446.     XprIO -> xpr_squery    = xpr_squery;
  1447.     XprIO -> xpr_getptr    = xpr_getptr;
  1448.  
  1449.         /* Try to open the library. */
  1450.  
  1451.     if(XProtocolBase = (struct Library *)OpenLibrary(LastXprLibrary,0))
  1452.     {
  1453.             /* Set up the library. */
  1454.  
  1455.         ClearSerial();
  1456.  
  1457.         TransferBits = XProtocolSetup(XprIO);
  1458.  
  1459.         RestartSerial(FALSE);
  1460.  
  1461.         DeleteTransferPanel(IgnoreOptions != TRUE);
  1462.  
  1463.             /* Successful initialization? */
  1464.  
  1465.         if(TransferBits & XPRS_SUCCESS)
  1466.         {
  1467.             SetTransferMenu(TRUE);
  1468.  
  1469.             if(TransferBits & XPRS_HOSTMON)
  1470.                 ConTransfer = ConTransferHost;
  1471.             else
  1472.                 ConTransfer = ConProcess;
  1473.  
  1474.             if(TransferBits & XPRS_HOSTNOWAIT)
  1475.             {
  1476.                 if(!HostReadBuffer)
  1477.                     HostReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
  1478.             }
  1479.             else
  1480.             {
  1481.                 if(HostReadBuffer)
  1482.                 {
  1483.                     FreeVecPooled(HostReadBuffer);
  1484.  
  1485.                     HostReadBuffer = NULL;
  1486.                 }
  1487.             }
  1488.  
  1489.             return(TRUE);
  1490.         }
  1491.         else
  1492.         {
  1493.             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  1494.  
  1495.             CloseLibrary(XProtocolBase);
  1496.  
  1497.             XProtocolBase = NULL;
  1498.  
  1499.             LastXprLibrary[0] = 0;
  1500.  
  1501.             TransferBits = 0;
  1502.  
  1503.             ConTransfer = ConProcess;
  1504.  
  1505.             SetTransferMenu(FALSE);
  1506.         }
  1507.     }
  1508.     else
  1509.     {
  1510.         ConTransfer = ConProcess;
  1511.  
  1512.         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  1513.     }
  1514.  
  1515.     return(FALSE);
  1516. }
  1517.  
  1518.     /* SaveProtocolOpts():
  1519.      *
  1520.      *    Save the current protocol settings to an environment variable.
  1521.      */
  1522.  
  1523. VOID
  1524. SaveProtocolOpts()
  1525. {
  1526.         /* It's time to save the altered options. */
  1527.  
  1528.     if(NewOptions && XProtocolBase)
  1529.     {
  1530.         UBYTE NameBuffer[40],i;
  1531.  
  1532.             /* Strip the `.library' part. */
  1533.  
  1534.         strcpy(NameBuffer,FilePart(LastXprLibrary));
  1535.  
  1536.         for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  1537.         {
  1538.             if(NameBuffer[i] == '.')
  1539.             {
  1540.                 NameBuffer[i] = 0;
  1541.                 break;
  1542.             }
  1543.         }
  1544.  
  1545.             /* Cause the xpr.library to prompt for
  1546.              * input. We expect the library to fill
  1547.              * the prompt string with the default
  1548.              * settings. The resulting string is
  1549.              * intercepted by xpr_stealopts, saved
  1550.              * to an environment variable and will
  1551.              * serve as a reinitialization string
  1552.              * later.
  1553.              */
  1554.  
  1555.         XprIO -> xpr_filename    = NULL;
  1556.         XprIO -> xpr_gets    = xpr_stealopts;
  1557.         XprIO -> xpr_extension    = 0;
  1558.         XprIO -> xpr_options    = NULL;
  1559.  
  1560.         ClearSerial();
  1561.  
  1562.         XProtocolSetup(XprIO);
  1563.  
  1564.         DeleteTransferPanel(FALSE);
  1565.  
  1566.             /* Save the options in case anything goes
  1567.              * wrong.
  1568.              */
  1569.  
  1570.         NewOptions = FALSE;
  1571.  
  1572.         SetEnvDOS(NameBuffer,ProtocolOptsBuffer);
  1573.  
  1574.             /* Reinitialize the library. */
  1575.  
  1576.         XprIO -> xpr_filename    = ProtocolOptsBuffer;
  1577.         XprIO -> xpr_gets    = xpr_gets;
  1578.         XprIO -> xpr_extension    = 4;
  1579.         XprIO -> xpr_options    = xpr_options;
  1580.  
  1581.         XProtocolSetup(XprIO);
  1582.  
  1583.         RestartSerial(FALSE);
  1584.  
  1585.         DeleteTransferPanel(FALSE);
  1586.     }
  1587. }
  1588.  
  1589.     /* SelectProtocol(STRPTR Name,struct Window *ParentWindow):
  1590.      *
  1591.      *    Select a different transfer protocol library using
  1592.      *    the asl.library file requester.
  1593.      */
  1594.  
  1595. BYTE __regargs
  1596. SelectProtocol(STRPTR Name,struct Window *ParentWindow)
  1597. {
  1598.     strcpy(SharedBuffer,LastXprLibrary);
  1599.  
  1600.     if(PickFile(Window,"Libs:","xpr#?.library",LocaleString(MSG_TERMXPR_SELECT_TRANSFER_PROTOCOL_TXT),SharedBuffer,NT_LIBRARY))
  1601.     {
  1602.         if(Stricmp(SharedBuffer,LastXprLibrary))
  1603.         {
  1604.             strcpy(LastXprLibrary,SharedBuffer);
  1605.  
  1606.             return(TRUE);
  1607.         }
  1608.     }
  1609.  
  1610.     return(FALSE);
  1611. }
  1612.  
  1613.     /* TransferCleanup():
  1614.      *
  1615.      *    We did a file transfer (auto-download?) and
  1616.      *    will need to close the transfer window.
  1617.      */
  1618.  
  1619. VOID
  1620. TransferCleanup()
  1621. {
  1622.     if(DidTransfer)
  1623.     {
  1624.         if(TransferFailed || TransferError)
  1625.         {
  1626.             WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1627.  
  1628.             DeleteTransferPanel(TRUE);
  1629.         }
  1630.         else
  1631.         {
  1632.             if(TransferWindow)
  1633.             {
  1634.                 WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1635.  
  1636.                 WaitTime(2,0);
  1637.             }
  1638.  
  1639.             DeleteTransferPanel(FALSE);
  1640.         }
  1641.  
  1642.         if(SendAbort && UsesZModem)
  1643.             SerWrite(ZModemCancel,20);
  1644.  
  1645.         SendAbort = FALSE;
  1646.  
  1647.         if(Config -> CommandConfig -> DownloadMacro[0])
  1648.             SerialCommand(Config -> CommandConfig -> DownloadMacro);
  1649.  
  1650.         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1651.  
  1652.         DidTransfer = FALSE;
  1653.     }
  1654.     else
  1655.     {
  1656.         if(TransferFailed || TransferError)
  1657.         {
  1658.             WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1659.  
  1660.             DeleteTransferPanel(TRUE);
  1661.         }
  1662.         else
  1663.         {
  1664.             if(TransferWindow)
  1665.             {
  1666.                 WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1667.  
  1668.                 WaitTime(2,0);
  1669.             }
  1670.  
  1671.             DeleteTransferPanel(FALSE);
  1672.         }
  1673.     }
  1674.  
  1675.     BinaryTransfer = TRUE;
  1676.  
  1677.     Status = STATUS_READY;
  1678.  
  1679.     ReleaseWindows();
  1680. }
  1681.  
  1682.     /* RemoveUploadListItem(STRPTR Name):
  1683.      *
  1684.      *    Remove a named item from the upload list.
  1685.      */
  1686.  
  1687. VOID __regargs
  1688. RemoveUploadListItem(STRPTR Name)
  1689. {
  1690.     BPTR NameLock;
  1691.  
  1692.     if(NameLock = Lock(Name,ACCESS_READ))
  1693.     {
  1694.         struct GenericList    *List = GenericListTable[GLIST_UPLOAD];
  1695.         struct Node        *Node;
  1696.         STRPTR             Base = FilePart(Name);
  1697.  
  1698.         ObtainSemaphore(&List -> ListSemaphore);
  1699.  
  1700.         Node = (struct Node *)List -> ListHeader . mlh_Head;
  1701.  
  1702.         while(Node -> ln_Succ)
  1703.         {
  1704.             if(!Stricmp(Base,FilePart(Node -> ln_Name)))
  1705.             {
  1706.                 BPTR ListLock;
  1707.  
  1708.                 if(ListLock = Lock(Node -> ln_Name,ACCESS_READ))
  1709.                 {
  1710.                     if(SameLock(ListLock,NameLock) == LOCK_SAME)
  1711.                     {
  1712.                         Forbid();
  1713.  
  1714.                         ReleaseSemaphore(&List -> ListSemaphore);
  1715.  
  1716.                         DeleteGenericListNode(List,Node);
  1717.  
  1718.                         Permit();
  1719.  
  1720.                         UnLock(ListLock);
  1721.  
  1722.                         UnLock(NameLock);
  1723.  
  1724.                         return;
  1725.                     }
  1726.  
  1727.                     UnLock(ListLock);
  1728.                 }
  1729.             }
  1730.  
  1731.             Node = Node -> ln_Succ;
  1732.         }
  1733.  
  1734.         ReleaseSemaphore(&List -> ListSemaphore);
  1735.  
  1736.         UnLock(NameLock);
  1737.     }
  1738. }
  1739.